using System;
using System.Collections.Generic;
using System.Text;

using SSOConfig;
using SSOConfigTool;
using System.Security.Cryptography;

namespace SSOConfigTool.Console
{
    /// <summary>
    /// Console application class for accessing SSO 
    /// </summary>
    class Program
    {
        #region Properties wrapping args

        private static string ConfigFilePath
        {
            get
            {
                return ArgumentHelper.GetArgument(Switches.ConfigFilePath);
            }
        }

        private static string ClassPath
        {
            get
            {
                return ArgumentHelper.GetArgument(Switches.ClassPath);
            }
        }

        private static string AssemblyName
        {
            get
            {
                return ArgumentHelper.GetArgument(Switches.AssemblyName);
            }
        }

        private static string ApplicationName
        {
            get
            {
                return ArgumentHelper.GetArgument(Switches.ApplicationName);
            }
        }

        private static string Namespace
        {
            get
            {
                return ArgumentHelper.GetArgument(Switches.Namespace);
            }
        }

        private static bool SaveToSSO
        {
            get
            {
                return ArgumentHelper.HasArgument(Switches.SaveToSSO);
            }
        }

        private static bool GenerateClass
        {
            get
            {
                return ArgumentHelper.HasArgument(Switches.GenerateClass);
            }
        }

        private static bool GenerateAssembly
        {
            get
            {
                return ArgumentHelper.HasArgument(Switches.GenerateAssembly);
            }
        }

        private static bool CopyFromSSO
        {
            get
            {
                return ArgumentHelper.HasArgument(Switches.CopyFromSSO);
            }
        }

        #endregion

        #region Static methods

        static void Main(string[] args)
        {
            ArgumentHelper.LoadArguments(args);

            if (SaveToSSO)
            {
                //save to SSO comes from XML:
                EnsureSwitch(Switches.ConfigFilePath);
                SSOApplication app = SSOApplication.LoadFromXml(ConfigFilePath);
                app.SaveToSSO();
            }

            if (GenerateClass)
            {
                EnsureSwitch(Switches.ClassPath);
                EnsureSwitch(Switches.Namespace);
                SSOApplication app = GetApplication();
                ConfigTool.GenerateClass(app, Namespace, ClassPath);
            }

            if (GenerateAssembly)
            {
                EnsureSwitch(Switches.AssemblyName);
                EnsureSwitch(Switches.Namespace);
                SSOApplication app = GetApplication();
                ConfigTool.GenerateAssembly(app, Namespace, AssemblyName);
            }

            if (CopyFromSSO)
            {
                EnsureSwitch(Switches.ApplicationName);
                EnsureSwitch(Switches.ConfigFilePath);
                SSOApplication app = SSOApplication.LoadFromSSO(ApplicationName);
                app.SaveToXml(ConfigFilePath);
            }

        }

        private static SSOApplication GetApplication()
        {
            //generate class can come from SSO or XML:
            EnsureAnySwitch(Switches.ConfigFilePath, Switches.ApplicationName);
            SSOApplication app = null;
            if (ArgumentHelper.HasArgument(Switches.ConfigFilePath))
            {
                app = SSOApplication.LoadFromXml(ConfigFilePath);
            }
            else
            {
                app = SSOApplication.LoadFromSSO(ApplicationName);
            }
            return app;
        }

        static void EnsureSwitch(string argumentName)
        {
            if (!ArgumentHelper.HasArgument(argumentName))
            {
                throw new ApplicationException(string.Format("{0} argument required", argumentName));
            }
        }

        static void EnsureAnySwitch(params string[] argumentNames)
        {
            foreach (string argumentName in argumentNames)
            {
                if (ArgumentHelper.HasArgument(argumentName))
                {
                    return;
                }
            }
            throw new ApplicationException(string.Format("Missing argument: {0}", argumentNames));
        }

        #endregion

        #region Private structs

        /// <summary>
        /// Switches = the possible inputs
        /// </summary>
        private struct Switches
        {
            public const string ConfigFilePath = "ConfigFilePath";
            public const string SaveToSSO = "SaveToSSO";
            public const string GenerateClass = "GenerateClass";
            public const string GenerateAssembly = "GenerateAssembly";
            public const string CopyFromSSO = "CopyFromSSO";
            public const string ClassPath = "ClassPath";
            public const string AssemblyName = "AssemblyName";
            public const string ApplicationName = "ApplicationName";
            public const string Namespace = "Namespace";
        }

        #endregion

    }
}
